#include "Traod.h"

_TRAJECTORY_BEGIN_

using namespace utilities;
using std::vector;
using std::pair;
using std::string;
using std::cout;
using std::endl;
using std::ifstream;
using std::ofstream;
using std::stringstream;

Traod::Traod()
{
	m_CardinalCoarsePartition = 0;
	m_CardinalDetailPartition = 0;
	std::cout << "The Traod is created." << std::endl;
}

/************************************************************************/
/*	Read the data from the file and store it into m_Points.             */
/*	Parameters:															*/
/*		sFileName - the input file name									*/
/*		delim - the delim of the string									*/
/************************************************************************/
void Traod::readDataFromFile(const std::string& sFileName, const char delim)
{
	ifstream in;
	//////////////////////////////////////////////////////////////////////////
	//	Open the file
	//////////////////////////////////////////////////////////////////////////
	in.open(sFileName.c_str(), std::ios::in|std::ios::binary);
	if (NULL == in)
	{
		std::cerr << "The file " << sFileName << " is not exists!\n";
	}
	else
	{
		cout << "The file is opened.\n";
	}

	//////////////////////////////////////////////////////////////////////////
	//	Read data by the mask
	//////////////////////////////////////////////////////////////////////////
	int count = 0;
	string sLastName("");
	float dTmpLatitude;
	float dTmpLongitude;
	while (!in.eof())
	{
		string strBuf;
		getline(in, strBuf, '\n');
		vector<std::string> vStr;
		split(strBuf, delim, vStr);
		
		if (vStr.empty())
		{
			continue;
		}

		if (vStr[5] != sLastName)	//	A new trajectory
		{
			vector<pair<float, float>> *newTrajectory = new vector<pair<float, float>>();
			m_Points.push_back(newTrajectory);
			m_TrajectoryName.push_back(vStr[5]);
			sLastName = vStr[5];
		}
		
		std::istringstream *iss1 = new std::istringstream(vStr[6]);
		*iss1 >> dTmpLatitude;
		delete iss1;

		std::istringstream *iss2 = new std::istringstream(vStr[7]);
		*iss2 >> dTmpLongitude;
		delete iss2;
		pair<float, float> point(dTmpLatitude, dTmpLongitude);
		int iCurrentTrajectory = m_Points.size() - 1;
		m_Points[iCurrentTrajectory]->push_back(point);	//	Add the point to the latest trajectory
		
		vStr.clear();
		strBuf.clear();
		count++;
		if (count % 10000 == 0)
		{
			cout << count << " records has been processed\n";
		}
	}

	in.close();
	/*for (int i = 0; i < (int)m_Points.size(); i++)
	{
		cout << "For trajectory " << i << endl;
		vector<pair<double, double>> *tmp = m_Points[i];
		for (int j = 0; j < (int)m_Points[i]->size(); j++)
		{
			pair<double, double> tp = (*tmp)[j];
			cout << "Point " << j << ":[" << tp.first << "," << tp.second << "]\n";
		}
	}*/
	cout << "End read data from file.\n";
	cout << "The trajectory number is:" << m_Points.size() << endl;

	cout << "There length is:\n";

	for (int i = 0; i < (int)m_Points.size(); i++)
	{
		vector<std::pair<float, float>> *tra = m_Points[i];
		cout << "\tFor trajectory " << i << ":" << tra->size() << endl;
	}
}

void Traod::split(const std::string& s, char delim, std::vector<std::string>& vStr)
{

	string::size_type i = 0;
	string::size_type j = s.find(delim);
	while (j != string::npos)
	{
		vStr.push_back(s.substr(i, j - i));
		i = ++j;
		j = s.find(delim, j);
		if (j == string::npos)
		{
			vStr.push_back(s.substr(i, s.length()));
		}
	}

}

float Traod::calculateMDLnopar(int iTraNum, int i, int j)
{
	float nopar = 0;
	vector<pair<float, float>> *tra = m_Points[iTraNum];	/*	Get the trajectory	*/
	pair<float, float> tmpPoint1, tmpPoint2;

	/*	Calculate the MDLnopar	*/
	for (int k = i; k < j - 1; k++)
	{
		tmpPoint1 = (*tra)[k];
		tmpPoint2 = (*tra)[k + 1];
		nopar += calculateEuclideanDistance(tmpPoint1.first, tmpPoint1.second, tmpPoint2.first, tmpPoint2.second);
	}
	nopar = static_cast<float>(log(nopar) / log(2.0));

	return nopar;
}

float Traod::calculateMDLpar(int iTraNum, int i, int j)
{
	float par = 0;
	float LH = 0;
	float DHper = 0, DHthe = 0;
	vector<pair<float, float>> *tra = m_Points[iTraNum];	/*	Get the trajectory	*/
	pair<float, float> tmpPoint1 = (*tra)[i];
	pair<float, float> tmpPoint2 = (*tra)[j];	/*	Store point j	*/
	pair<float, float> tmpPoint3;
	pair<float, float> tmpPoint4;

	LH = static_cast<float>(log(calculateEuclideanDistance(tmpPoint1.first, tmpPoint1.second, tmpPoint2.first, tmpPoint2.second)) / log(2.0));
	for (int k = i; k < j - 1; k++)
	{
		tmpPoint3 = (*tra)[k];
		tmpPoint4 = (*tra)[k + 1];
		DHper += calculatePerpendicularDistanceEx(tmpPoint1.first, tmpPoint1.second, tmpPoint2.first, tmpPoint2.second, tmpPoint3.first, tmpPoint3.second, tmpPoint4.first, tmpPoint4.second);
		DHthe += calculateAngleDistanceEx(tmpPoint1.first, tmpPoint1.second, tmpPoint2.first, tmpPoint2.second, tmpPoint3.first, tmpPoint3.second, tmpPoint4.first, tmpPoint4.second);
	}

	par = static_cast<float>(LH + log(DHper) / log(2.0) + log(DHthe) / log(2.0));

	return par;
}

void Traod::calculateCoarsePartition(int iTraId)
{
	vector<pair<float, float>> *tra = m_Points[iTraId];
	vector<pair<float, float>> *traCP = new vector<pair<float, float>>();
	
	traCP->push_back((*tra)[0]);	/*	Put the 1-st point into CPi */
	
	int startIndex = 0, length = 1;

	while (startIndex + length < (int)tra->size())
	{
		int currentIndex = startIndex + length;
		float par = calculateMDLpar(iTraId, startIndex, currentIndex);
		float nopar = calculateMDLnopar(iTraId, startIndex, currentIndex);
		/* check if partitioning at the current point makes the MDL cost larger than not partitioning */
		if (par > nopar)
		{
			traCP->push_back((*tra)[currentIndex]);
			startIndex = currentIndex - 1;
			length = 1;
		}
		else
		{
			length += 1;
		}
	}
	traCP->push_back((*tra)[tra->size() - 1]);	/*	Add the last point into the set	*/
	m_CoarsePartition.push_back(traCP);
}

/************************************************************************/
/*	Coarse partition the trajectories. The result is saved in			*/
/*	m_CoarsePartition.													*/
/************************************************************************/
void Traod::coarsePartition()
{
	cout << "Begin to partition the trajectories.\n";
	/*for (int i = 0; i < (int)m_Points.size(); i++)
	{
		calculateCoarsePartition(i);
		vector<pair<float, float>> *CP = m_CoarsePartition[i];
		//cout << "\nFor trajectory " << i << " the coarse size is:" << CP->size() << endl;
		cout << "\t\tThey are:";
		for (int j = 0; j < (int)CP->size(); j++)
		{
			cout << "[" << ((*CP)[j]).first << "," << ((*CP)[j]).second << "] ";
		}
	}*/
	cout << "End partition." << endl;
}

/************************************************************************/
/*	Calculate the CTR. Store the information into m_CTR.                */
/*	Parameters:															*/
/*		D	 - distance													*/
/*		Wper - weight of perpendicular factor							*/
/*		Wpar - weight of parallel factor								*/
/*		Wthe - weight of angle factor									*/
/*		p	 - the rate p that Li should at least satisfy				*/
/************************************************************************/
void Traod::calculateOP(float D, float Wper, float Wpar, float Wthe, float p)
{
	/*	Calculate the CP set	*/
	double dMax = 100, dMin = 0;
	float dAvg = 0.0f;
	int iNum = 0;
	cout << "\tCalculate the CP set.\n";
	vector<vector<vector<vector<pair<pair<float, float>, pair<float, float>>>>>> CP;	/*	The set of TRk's t-partition within the distance D from Lj	*/
	CP.resize(m_Points.size());
	vector<vector<vector<vector<float>>>> distCP;	/*	The set of distance of TRk's t-partition within the distance D from Lj	*/
	vector<vector<float>> means;	/*	The means of distance for each Lj	*/
	//means.resize(100);
	vector<vector<int>> meansNum;
	//meansNum.resize(m_Points.size());
	for (int i = 0; i < (int)m_Points.size(); i++)
	{
		vector<int> meansNumTRi;	/*	The number of neighbor of Lj	*/
		meansNum.push_back(meansNumTRi);
		vector<float> meansTRi;	/*	The means of distance for each Lj in trajectory i	*/
		means.push_back(meansTRi);
		vector<vector<vector<float>>> distCPi;	/*	store all the distance set information Lj of CPi	*/
		distCP.push_back(distCPi);
		vector<pair<float, float>> *TRi = m_Points[i];
		vector<vector<vector<pair<pair<float, float>, pair<float, float>>>>> CPi;	/* store all the set information Lj	of CPi	*/
		CPi.resize(TRi->size() - 1);
		CP.push_back(CPi);
		for (int j = 0; j < (int)TRi->size() - 1; j++)
		{
			vector<vector<float>> distLiNeighbors;	/*	store all the distance of neighbors in other TR of Lj	*/
			distCP[i].push_back(distLiNeighbors);
			vector<vector<pair<pair<float, float>, pair<float, float>>>> LiNeighbors;	/*	store all the neighbors Ll in other TR of Lj	*/
			(CP[i]).push_back(LiNeighbors);
			pair<float, float> tmpPoint1 = (*TRi)[j];
			pair<float, float> tmpPoint2 = (*TRi)[j + 1];
			int dMeansNumTRi = 0;
			float dMeansTRi = 0.0;
			for (int k = 0; k < (int)m_Points.size(); k++)
			{
				vector<float> distLiTRkNeighbors;	/*	store all the distance of the neighbors Ll in TRk of Lj	*/
				distCP[i][j].push_back(distLiTRkNeighbors);
				vector<pair<pair<float, float>, pair<float, float>>> LiTRkNeighbors;	/*	store all the neighbors Ll in TRk of Lj	*/
				(CP[i])[j].push_back(LiTRkNeighbors);
				vector<pair<float, float>> *TRk = m_Points[k];
				for (int l = 0; l < (int)TRk->size() - 1; l++)
				{
					pair<float, float> tmpPoint3 = (*TRk)[l];
					pair<float, float> tmpPoint4 = (*TRk)[l + 1];
					if (i != k)	//	Not the same trajectories
					{
						float dist = calculateDistance(tmpPoint1.first, tmpPoint1.second, tmpPoint2.first, tmpPoint2.second, tmpPoint3.first, tmpPoint3.second, tmpPoint4.first, tmpPoint4.second, Wper, Wpar, Wthe);
						if (dist > dMax)
						{
							dMax = dist;
						}
						if (dist < dMin)
						{
							dMin = dist;
						}

						if (dist < D)	//	If Ll is the neighbor of Lj, add it into the set
						{
							dAvg += dist;
							iNum++;
							//cout << dist << endl;
							pair<pair<float, float>, pair<float, float>> Ll;
							Ll.first = tmpPoint3;
							Ll.second = tmpPoint4;
							distCP[i][j][k].push_back(dist);
							(CP[i])[j][k].push_back(Ll);
							dMeansNumTRi++;
							dMeansTRi += dist;
						}
					}
				}
			}
			meansNum[i].push_back(dMeansNumTRi);
			means[i].push_back(dMeansTRi);
		}
		//cout << "\t\tThere are " << i << "trajectories has been used.\n";
	}
	cout << "The max dist is " << dMax << ", and the min dist is:" << dMin << ", the average length is:" << dAvg << ", " << iNum << ", " << (dAvg / iNum) <<endl;
	cout << "\tEnd of calculate CP set.\n";

	/*	Calculate the CTR set	*/
	cout << "\tCalculate the CTR set.\n";
	for (int i = 0; i < (int)m_Points.size(); i++)
	{ 
		vector<vector<vector<pair<pair<float, float>, pair<float, float>>>>> CPi = CP[i];	//	The CP of trajectory i	
		vector<pair<float, float>> *TRi = m_Points[i];
		vector<vector<int>> CTRi;	//	The set information of trajectory i
		m_CTR.push_back(CTRi);
		for (int j = 0; j < (int)CPi.size(); j++)
		{
			vector<int> CTRiLj;	//	The set of Lj	
			m_CTR[i].push_back(CTRiLj);
			vector<vector<pair<pair<float, float>, pair<float, float>>>> LiNeighbors = (CPi)[j];
			pair<float, float> tmpPoint1 = (*TRi)[j];
			pair<float, float> tmpPoint2 = (*TRi)[j + 1];
			float lengthLj = calculateEuclideanDistance(tmpPoint1.first, tmpPoint1.second, tmpPoint2.first, tmpPoint2.second);
			for (int k = 0; k < (int)m_Points.size(); k++)
			{
				vector<std::pair<pair<float, float>, pair<float, float>>> LiTRkNeighbor = LiNeighbors[k];
				float lengthLl = 0.0;
				for (int l = 0; l < (int)LiTRkNeighbor.size(); l++)
				{
					pair<pair<float, float>, pair<float, float>> Ll = LiTRkNeighbor[l];
					if (i != k)	//	Not the same trajectories
					{
						lengthLl += calculateEuclideanDistance(Ll.first.first, Ll.first.second, Ll.second.first, Ll.second.second);
						if (lengthLl > lengthLj)
						{
							m_CTR[i][j].push_back(k);	//	If enough length is close to Lj, then TRk is close to Lj
						}
					}
				}
			}

		}

	}
	cout << "\tEnd of calculate CTR set.\n";

	for (int i = 0; i < (int)CP.size(); i++)
	{
		for (int j = 0; j < (int)CP[i].size(); j++)
		{
			for (int k = 0; k < (int)CP[i][j].size(); k++)
			{
				CP[i][j][k].clear();
			}
			CP[i][j].clear();
		}
		CP[i].clear();
	}



	/*	Calculate the mean density of Lj	*/
	cout << "\tCalculate the means\n";
	for (int i = 0; i < (int)means.size(); i++)
	{
		vector<float> meansTRi = means[i];
		vector<int> meansNumTRi = meansNum[i];
		for (int j = 0; j < (int)meansTRi.size(); j++)
		{
			meansTRi[j] /= meansNumTRi[j];
		}
	}
	cout << "\tEnd of the calculation of the mean.\n";

	/*	Calculate the standard deviation of Lj	*/
	cout << "\tCalculate the standard deviation for each L.\n";
	vector<vector<float>> dSD;	/*	The set of standard deviation of all Lj	*/
	for (int i = 0; i < (int)means.size(); i++)
	{
		vector<float> dSDTRi;	/*	The set of standard deviation of Lj in TRi	*/
		dSD.push_back(dSDTRi);
		vector<float> meansTRi = means[i];
		vector<vector<vector<float>>> distCPi = distCP[i];	/*	store all the distance set information Lj of CPi	*/
		float tmpSD = 0.0;
		for (int j = 0; j < (int)meansTRi.size(); j++)
		{
			vector<vector<float>> distLiNeighbors = distCPi[j];	//	store all the distance of neighbors in other TR of Lj	
			for (int k = 0; k < (int)distLiNeighbors.size(); k++)
			{
				vector<float> distLiTRkNeighbors = distLiNeighbors[k];
				for (int l = 0; l < (int)distLiTRkNeighbors.size(); l++)
				{
					tmpSD += pow(distLiTRkNeighbors[l] - meansTRi[j], 2);	//	Calculate the standard deviation of Lj
				}
			}
			tmpSD = sqrt(tmpSD);
			dSD[i].push_back(tmpSD);
		}
		
	}
	cout << "\tEnd of the calculation of the standard deviation each L.\n";
	
	/*	Calculate the density for each Lj	*/
	cout << "\tCalculate the density for each Lj.\n";
	vector<vector<vector<vector<pair<pair<float, float>, pair<float, float>>>>>> densityCP;	//	The set of TRk's t-partition within the distance sigma from Lj	
	for (int i = 0; i < (int)m_Points.size(); i++)
	{
		vector<float> dSDTRi = dSD[i];	//	The standard deviation of TRi	
		vector<vector<vector<pair<pair<float, float>, pair<float, float>>>>> densityCPi;	// store all the set information Lj	of densityCPi
		densityCP.push_back(densityCPi);
		vector<pair<float, float>> *TRi = m_Points[i];
		for (int j = 0; j < (int)TRi->size() - 1; j++)
		{
			vector<vector<pair<pair<float, float>, pair<float, float>>>> densityLiNeighbors;	//	store all the neighbors Ll in other TR of Lj
			densityCP[i].push_back(densityLiNeighbors);
			pair<float, float> tmpPoint1 = (*TRi)[j];
			pair<float, float> tmpPoint2 = (*TRi)[j + 1];
			for (int k = 0; k < (int)m_Points.size(); k++)
			{
				vector<pair<pair<float, float>, pair<float, float>>> densityLiTRkNeighbors;	//	store all the neighbors Ll in TRk of Lj	
				densityCP[i][j].push_back(densityLiTRkNeighbors);
				vector<pair<float, float>> *TRk = m_Points[k];
				for (int l = 0; l < (int)TRk->size() - 1; l++)
				{
					pair<float, float> tmpPoint3 = (*TRk)[l];
					pair<float, float> tmpPoint4 = (*TRk)[l + 1];
					if (i != k)	//	Not the same trajectories
					{
						float dist = calculateDistance(tmpPoint1.first, tmpPoint1.second, tmpPoint2.first, tmpPoint2.second, tmpPoint3.first, tmpPoint3.second, tmpPoint4.first, tmpPoint4.second, Wper, Wpar, Wthe);
						if (dist < dSDTRi[j])	//	If Ll is the neighbor of Lj, add it into the set
						{
							pair<pair<float, float>, pair<float, float>> Ll;
							Ll.first = tmpPoint3;
							Ll.second = tmpPoint4;
							densityCP[i][j][k].push_back(Ll);
						}
					}
				}
			}
		}
	} 
	
	vector<vector<int>> densityL;
	for (int i = 0; i < (int)densityCP.size(); i++)
	{
		vector<int> densityLj;	//	The density of Lj	
		densityL.push_back(densityLj);
		vector<vector<vector<pair<pair<float, float>, pair<float, float>>>>> densityCPi = densityCP[i];
		//cout << "\t\tFor trajectory " << i << ":\n";
		for (int j = 0; j < (int)densityCPi.size(); j++)
		{
			int cardinalNumberLj = 0;	//	The cardinal number of density of TRk to Lj	
			vector<vector<pair<pair<float, float>, pair<float, float>>>> densityLiNeighbors = densityCPi[j];
			for (int k = 0; k < (int)densityLiNeighbors.size(); k++)
			{
				cardinalNumberLj += densityLiNeighbors[k].size();
			}
			//cout << "\t\t\tThe density of L" << j << " is:" << cardinalNumberLj << endl;
			densityL[i].push_back(cardinalNumberLj);
		}
		
	}
	cout << "\tEnd of the calculation of density for each Lj.\n";

	/*	Calculate the cardinal number of all the partitions	*/
	cout << "\tCalculate the cardinal number of all the trajectories.\n";
	for (int i = 0; i < (int)m_Points.size(); i++)
	{
		m_CardinalDetailPartition += m_Points[i]->size() - 1;
	}
	cout << "\t\tThe cardinal number of the base unit partitions is:" << m_CardinalDetailPartition << endl;
	cout << "\tEnd of the calculation of the cardinal number of the trajectories.\n";

	/*	Calculate the adj of all Lj	*/
	cout << "\tCalculate the adj for each L.\n";
	int iSumOfDensity = 0;
	for (int i = 0; i < (int)densityL.size(); i++)
	{
		for (int j = 0; j < (int)densityL[i].size(); j++)
		{
			iSumOfDensity += densityL[i][j];	
		}
	}

	float dNumerator = static_cast<double>(iSumOfDensity / m_CardinalDetailPartition);

	vector<vector<float>> adjL;
	for (int i = 0; i < (int)densityL.size(); i++)
	{
		vector<float> adjTRi;
		adjL.push_back(adjTRi);
		//cout << "\t\tFor trajectory " << i << ":\n";
		for (int j = 0; j < (int)densityL[i].size(); j++)
		{
			float dTmp = dNumerator / densityL[i][j];
			adjL[i].push_back(dTmp);
			//cout << "\t\t\tThe adj of L" << j << " is " << dTmp << endl; 
		}
		
	}
	cout << "\tEnd of the calculation the adj for each L.\n";

	/*	Calculate the factor of cardinal CTR  for each Lj	*/
	cout << "\tCalculate the factor of cardinal CTR for each Lj.\n";
	vector<vector<int>> cardinalCTR;
	for (int i = 0; i < (int)m_CTR.size(); i++)
	{
		vector<vector<int>> CTRi = m_CTR[i];	//	The set information of trajectory i	
		vector<int> cardinalCTRi;	//	The set of cardinal of L in CTRi	
		for (int j = 0; j < (int)CTRi.size(); j++)
		{
			cardinalCTRi.push_back(CTRi[j].size());
		}
		cardinalCTR.push_back(cardinalCTRi);
	}
	cout << "\tEnd of the calculation of the factor of cardinal CTR for each Lj.\n";

	/*	Calculate the OP set of all the trajectories	*/
	for (int i = 0; i < (int)cardinalCTR.size(); i++)
	{
		vector<int> cardinalCTRi = cardinalCTR[i];
		vector<float> adjTRi = adjL[i];
		vector<bool> OPTRi;
		for (int j = 0; j < (int)cardinalCTRi.size(); j++)
		{
			float tmpF = ceil(cardinalCTRi[j] * adjTRi[j]);
			float tmpP = ceil((1 - p) * (int)m_Points.size());
			if ( tmpF <= tmpP)
			{
				//cout << "A outlier partition found!\n";
				//cout << "\t\t\ttmpF:" << tmpF << ",size:" << tmpP << endl;
				OPTRi.push_back(true);
			}
			else
			{
				OPTRi.push_back(false);
			}
		}
		m_OP.push_back(OPTRi);
	}

	//////////////////////////////////////////////////////////////////////////
	//	Test output
	//////////////////////////////////////////////////////////////////////////
	/*cout << "The size of m_CTR:" << m_CTR.size() << endl;
	for (int i = 0; i < (int)m_CTR.size(); i++)
	{
		vector<vector<vector<int>>> traSet = m_CTR[i];	//	The set information of trajectory i
		cout << "For each trajectory, the size of partition is:" << m_CTR[i].size() << endl;
		for (int j = 0; j < (int)traSet.size(); j++)
		{
			vector<vector<int>> traSetLj = traSet[j];	//	The set information of Lj in trajectory i
			cout << "\tFor current partition:\n";
			for (int k = 0; k < (int)traSetLj.size(); k++)
			{
				vector<int> traSetLjTRk = traSetLj[k];
				cout << "\t\tThe " << k << "th trajectory, size is:" << traSetLjTRk.size() << endl;
			}
		}
	}*/

}

void Traod::calculateOfrac(float F)
{
	/*	Calculate the Ofrac of the trajectories	*/
	for (int i = 0; i < (int)m_Points.size(); i++)
	{
		vector<pair<float, float>> *TRi = m_Points[i];
		vector<bool> OPTRi = m_OP[i];
		float allLen = 0.0;
		float outlierLen = 0.0;
		for (int j = 0; j < (int)TRi->size() - 1; j++)
		{
			pair<float, float> tmpPoint1 = (*TRi)[j];
			pair<float, float> tmpPoint2 = (*TRi)[j + 1];
			float distance = calculateEuclideanDistance(tmpPoint1.first, tmpPoint1.second, tmpPoint2.first, tmpPoint2.second);
			allLen += distance;
			if (OPTRi[j] == true)
			{
				outlierLen += distance;
			}
		}
		float tmpD = outlierLen / allLen;
		//cout << "tmpD:" << tmpD << endl;
		if ( tmpD>= F)
		{
			m_Ofrac.push_back(i);
		}
	}
	cout << "There are " << m_Ofrac.size() << " outlier trajectories.\n";
}

void Traod::outputResult(const string& strFileName)
{
	ofstream outFile;
	outFile.open(strFileName.c_str(), std::ios::binary|std::ios::out);

	stringstream ss;

	int iOutlier = 0;
	for (int i = 0; i < (int)m_Points.size(); i++)
	{
		if (std::find(m_Ofrac.begin(), m_Ofrac.end(), i) == m_Ofrac.end())
		{
			iOutlier = 0;
		}
		else
		{
			iOutlier = 1;
		}
		for (int j = 0; j < (int)(*m_Points[i]).size(); j++)
		{ 
			ss << i << "\t" << m_TrajectoryName[i] << "\t" << j << "\t" << (*m_Points[i])[j].first << "\t" << (*m_Points[i])[j].second << "\t" << iOutlier << "\r\n";
			outFile << ss.str();
			ss.str("");
		}
	}

	outFile.close();
}

_TRAJECTORY_END_